#ifndef D1B7D38B_15C7_482C_BCDF_3CFF839F7D62
#define D1B7D38B_15C7_482C_BCDF_3CFF839F7D62

#include <iostream>
#include <pthread.h>
#include <cstdio>
#include <cstring>
#include <string>
#include <semaphore.h>
#include <vector>
#include <ctime>
#include <unistd.h>

template<class T>
class Ringqueue{
private:
	void P(sem_t* sem)
	{
		sem_wait(sem);
	}
	void V(sem_t* sem)
	{
		sem_post(sem);
	}
	void Lock(pthread_mutex_t& mutex)
	{
		pthread_mutex_lock(&mutex);
	}
	void Unlock(pthread_mutex_t& mutex)
	{
		pthread_mutex_unlock(&mutex);
	}
public:
	Ringqueue(int cap) : cap_(cap),ringqueue_(cap),c_index_(0),p_index_(0)
	{
		sem_init(&c_data_sem_,0,0);
		sem_init(&p_space_sem_,0,cap_);
		pthread_mutex_init(&c_mutex_,nullptr);
		pthread_mutex_init(&p_mutex_,nullptr);
	}
	void push(const T& in)
	{
		P(&p_space_sem_);                  // 锁放在信号量后面更能提高并发度
		Lock(p_mutex_);
		ringqueue_[p_index_] = in;
		p_index_++;
		p_index_ %= cap_;
		Unlock(p_mutex_);
		V(&c_data_sem_);
	}
	void pop(T* out)
	{
		P(&c_data_sem_);               
		Lock(c_mutex_);
		*out = ringqueue_[c_index_];
		c_index_++;
		c_index_ %= cap_;
		Unlock(c_mutex_);
		V(&p_space_sem_);
	}
	~Ringqueue()
	{
		sem_destroy(&c_data_sem_);
		sem_destroy(&p_space_sem_);
	}
private:
	std::vector<T> ringqueue_;
	int cap_;

	int c_index_;
	int p_index_;
	sem_t c_data_sem_;
	sem_t p_space_sem_;

	pthread_mutex_t c_mutex_;
	pthread_mutex_t p_mutex_;
};



#endif /* D1B7D38B_15C7_482C_BCDF_3CFF839F7D62 */
